package zhiquan.cai.BingFa;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 线程类模拟一个窗口卖100张火车票，四个窗口同时卖。
 *
 * 基于Runnable实现
 */
public class TicketTest2 implements Runnable{

    /**
     * 此变量在jvm内存模型的堆区域，在堆里面意味着它是共享资源，每个线程都可以对它进行读写操作，
     * 会衍生两个问题，可见性与操作原子性，详情查看jvm内存模型原理。
     * 线程安全最大的表征是在多线程环境下运行，每次运行结果不一样，与预期结果不同。
     */
    private int count = 100;

    /**
     * 此静态变量在方法区
     */
    //private static int count = 100;

    /**
     * java所有的并发编程以及多线程的知识都在此juc包里面
     */
    private Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        TicketTest2 t = new TicketTest2();
        Thread t1 = new Thread(t,"窗口A");
        Thread t2 = new Thread(t,"窗口B");
        Thread t3 = new Thread(t,"窗口C");
        Thread t4 = new Thread(t,"窗口D");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }

    public void run() {
        while(count > 0) {
            //上锁，使用“同步代码块“使线程间同步，不然会出现线程不安全的问题
            synchronized(this){
                if(count > 0) {//双重校验
                    System.out.println(Thread.currentThread().getName() + "售出第" + count + "张火车票");
                    count--;
                    try {
                        Thread.sleep(50);//睡眠50毫秒
                    } catch (Exception e) {
                        // TODO: handle exception
                    }
                }
            }
        }
    }
}
